﻿using System;
using System.Diagnostics;
using System.Reflection;

namespace Fadd.Logging.Formatting
{
	/// <summary>
	/// Formats stack trace.
	/// </summary>
	public class StackTraceFormatter : IPartFormatter
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="StackTraceFormatter"/> class.
		/// </summary>
		public StackTraceFormatter()
		{
			SkipCount = 0;
			Count = 3;
			PadLength = 0;
		}

		/// <summary>
		/// Gets or sets number of frames to exclude.
		/// </summary>
		public int SkipCount { get; set; }

		/// <summary>
		/// Gets or sets number of frames to include.
		/// </summary>
		public int Count { get; set; }

		/// <summary>
		/// Gets or sets number of chars to pad.
		/// </summary>
		public int PadLength { get; set; }

		public string Format(LogEntry entry)
		{
			string temp = string.Empty;
			int stop = Math.Min(entry.StackFrames.Length, Count);
			for (int i = SkipCount; i < stop; ++i)
			{
				StackFrame frame = entry.StackFrames[i];
				if (frame == null)
				{
				    temp += "UnknownFrame <--";
                    continue;
                }

			    MethodBase method = frame.GetMethod();
                if (method == null)
                {
                    temp += "UnknownFrame <--";
                    continue;
                }

			    string typeName = method.ReflectedType == null ? "UnknownType" : method.ReflectedType.Name ?? "UnknownTypeName";
			    string methodName = method.Name ?? "UnknownMethodName";
			    temp = temp + typeName + "." + methodName + "<--";
			}

            if (temp.Length > 3)
				temp = temp.Remove(temp.Length - 3);

			return PadLength == 0 ? temp : temp.PadRight(PadLength);
		}
	}
}
